package club.kunlingou.dsc.common.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import sun.net.www.MessageHeader;

/**
 * 兼容http、https请求，内含转码逻辑
 * @since 1.6
 * @author goukunlin
 * 2019-12-16
 */
public class HttpsClientUtil {
	
	private static final SSLContext sslContext;
	
	private static final HostnameVerifier verifier;
	
	static {
		sslContext = getSSLContext();
		verifier = new HostnameVerifier() {
			@Override
			public boolean verify(String s, SSLSession sslSession) {
				return true;
			}
		};
	}
	
	private static SSLContext getSSLContext() {
		
		SSLContext sslContext;
		try {
			sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, new TrustManager[]{ new X509TrustManager() {
				@Override
				public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				}
				@Override
				public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				}
				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return new X509Certificate[0];
				}
			}}, new SecureRandom());
		} catch (Exception e) {
			e.printStackTrace();
			sslContext = null;
		}
		return sslContext;
	}
	
	public static String doGet(String resquestUrl) throws Exception {
		
		return doGet(resquestUrl, "UTF-8");
	}

	public static String doGet(String resquestUrl, String charset) throws Exception {
		
		InputStreamReader inputStreamReader;
		BufferedReader bufferedReader;
		StringBuffer buffer = new StringBuffer();
		
		URL url = new URL(URLencode(resquestUrl, charset));
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		if(conn instanceof HttpsURLConnection) {
			((HttpsURLConnection)conn).setSSLSocketFactory(sslContext.getSocketFactory());
			((HttpsURLConnection)conn).setHostnameVerifier(verifier);
		}
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setUseCaches(false);// no cache
		conn.setRequestMethod("GET");

		conn.connect();

		InputStream inputStream = conn.getInputStream();
		inputStreamReader = new InputStreamReader(inputStream, charset);
		bufferedReader = new BufferedReader(inputStreamReader);
		String str = null;
		while ((str = bufferedReader.readLine()) != null) {
			buffer.append(str);
		}

		conn.disconnect();

		return buffer.toString();
	}
	
	public static String doPost(String resquestUrl, String content) throws Exception {
		
		return doPost(resquestUrl, content, "UTF-8");
	}
	
	public static String doPost(String resquestUrl, String content, String charset) throws Exception {
		
		InputStreamReader inputStreamReader;
		BufferedReader bufferedReader;
		StringBuffer buffer = new StringBuffer();
		
		URL url = new URL(URLencode(resquestUrl, charset));
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		if(conn instanceof HttpsURLConnection) {
			((HttpsURLConnection)conn).setSSLSocketFactory(sslContext.getSocketFactory());
			((HttpsURLConnection)conn).setHostnameVerifier(verifier);
		}
		conn.addRequestProperty("connection", "Keep-Alive");
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setUseCaches(false);// no cache
		conn.setRequestMethod("POST");

		conn.connect();
		
		DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		out.write(content.getBytes(charset));
		out.flush();
        out.close();
        
		InputStream inputStream = conn.getInputStream();
		inputStreamReader = new InputStreamReader(inputStream, charset);
		bufferedReader = new BufferedReader(inputStreamReader);
		String str = null;
		while ((str = bufferedReader.readLine()) != null) {
			buffer.append(str);
		}
		inputStream.close();

		conn.disconnect();

		return buffer.toString();
	}
	
	private static String URLencode(String resquestUrl, String charset) throws UnsupportedEncodingException {
		String[] split = resquestUrl.split("\\?");
		StringBuffer sb = new StringBuffer();
		sb.append(split[0]);
		if(split.length>1) {
			sb.append("?");
			String[] params = split[1].split("&");
			for(String param : params) {
				String[] split2 = param.split("=");
				if(!sb.toString().endsWith("?")) {
					sb.append("&");
				}
				sb.append(split2[0]+"=");
				if(split2.length>1) {
					sb.append(URLEncoder.encode(split2[1], charset));
				}
			}
		}
		System.out.println("requestUrl:"+sb.toString());
		return sb.toString();
	}
}
